package com.hpsk.config.json;

import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.hpsk.enums.BaseEnum;
import com.hpsk.enums.BaseEnumDeserializer;
import com.hubspot.jackson.datatype.protobuf.ProtobufModule;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.TimeZone;

/**
 * JSON统一配置
 *
 * @author 李大鹏
 */
@Configuration
public class MyJackson2ObjectMapperBuilderCustomizer implements Jackson2ObjectMapperBuilderCustomizer {


    private static final DateTimeFormatter NORM_DATETIME_PATTERN = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN);
    private static final DateTimeFormatter NORM_DATE_PATTERN = DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN);
    private static final DateTimeFormatter NORM_TIME_PATTERN = DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN);

    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {

        jacksonObjectMapperBuilder.locale(Locale.CHINA)
                                  .serializationInclusion(JsonInclude.Include.ALWAYS)
                                  .timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()))
                                  .simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN)
                                  .featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
                                                     SerializationFeature.FAIL_ON_EMPTY_BEANS,
                                                     SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                                  .propertyNamingStrategy(PropertyNamingStrategies.LOWER_CAMEL_CASE)
                                  .serializerByType(Long.class, ToStringSerializer.instance)
                                  .serializerByType(BigInteger.class, ToStringSerializer.instance)
                                  .serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(NORM_DATETIME_PATTERN))
                                  .serializerByType(LocalDate.class, new LocalDateSerializer(NORM_DATE_PATTERN))
                                  .serializerByType(LocalTime.class, new LocalTimeSerializer(NORM_TIME_PATTERN))
                                  .deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(NORM_DATETIME_PATTERN))
                                  .deserializerByType(LocalDate.class, new LocalDateDeserializer(NORM_DATE_PATTERN))
                                  .deserializerByType(LocalTime.class, new LocalTimeDeserializer(NORM_TIME_PATTERN))
                                  .deserializerByType(BaseEnum.class, new BaseEnumDeserializer());
                                  // ProtobufModule 解决无限嵌套问题
//                                  .modulesToInstall(new ProtobufModule());
    }
}
